import Global from "@/store/Global";
import {DeviceDataType} from "@/config/Declare";

// let token = "30821c84jky2uj7xu5a0";
type DeviceEvent = (data: ReceiveDevice) => void

class TBWSService {
    private websocket: WebSocket = new WebSocket(Global.wsURL + Config.DEVICE_TELEMETRY + Global.token.token);
    private deviceEvents: { [key in string]: DeviceEvent } = {};
    // private sendDeviceParams: DeviceParams = {attrSubCmds: [], historyCmds: [], tsSubCmds: []};
    private _messageQueue:Array<[string,Array<DeviceDataType>]> = []

    constructor() {
        this.websocket.onmessage = (event)=>{
            for (let deviceEvent in this.deviceEvents){
                this.deviceEvents[deviceEvent](JSON.parse(event.data) as ReceiveDevice);
            }
        }
        this.websocket.onopen = () => {
            console.log('websocket open');
            for (let [entityId,dataType] of this._messageQueue){
                this.websocket.send(JSON.stringify(this.retainMessageData(entityId,dataType)));
            }
            this._messageQueue = [];
        }
        this.websocket.onerror = (e) => {
            console.warn('websocket error', e);
        }
    }

    //@ts-ignore
    receiveTelemetryData(event: MessageEvent) {

    }
    //@ts-ignore
    onTsDeviceEvent(entityId: string): void {

    }

    addDeviceEvent(entityId: string, dataType: Array<DeviceDataType>, event: DeviceEvent): void {
        if(this.websocket.readyState!==1){
            this._messageQueue.push([entityId,dataType])
        }else{
            this.websocket.send(JSON.stringify(this.retainMessageData(entityId,dataType)));
        }
        this.deviceEvents[entityId] = event;
    }

    retainMessageData(entityId:string,dataType:Array<DeviceDataType>): DeviceParams {
        let deviceParams: DeviceParams = {attrSubCmds: [], historyCmds: [], tsSubCmds: []};
        for (let type of dataType) {
            switch (type) {
                case DeviceDataType.Ts:
                    let tsSubCmds: TsSubCmds = {
                        cmdId: 10,
                        entityId: entityId,
                        entityType: "DEVICE",
                        keys: "",
                        scope: "LATEST_TELEMETRY"
                    };
                    deviceParams.tsSubCmds.push(tsSubCmds)
                    // this.sendDeviceParams.tsSubCmds.push(tsSubCmds);
                    break;
                case DeviceDataType.History:
                    let historyCmds: HistoryCmds = {
                        agg: "AVG",
                        endTs: 0,
                        entityId: entityId,
                        entityType: "DEVICE",
                        interval: 1000,
                        keys: "",
                        limit: 100,
                        startTs: 0
                    };
                    deviceParams.historyCmds.push(historyCmds)
                    // this.sendDeviceParams.historyCmds.push(historyCmds);
                    break;
                case DeviceDataType.Attr:
                    let attrSubCmds: AttrSubCmds = {
                        cmdId: 2, entityId: entityId, entityType: "DEVICE", scope: "CLIENT_SCOPE"
                    }
                    deviceParams.attrSubCmds.push(attrSubCmds)
                    // this.sendDeviceParams.attrSubCmds.push(attrSubCmds);
                    break;
            }
        }
        return deviceParams;
    }
}

const websocket = new TBWSService();
export default websocket;
